package com.magima.core.repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.magima.core.basic.Collection;
import com.magima.core.basic.Model;
import com.magima.core.basic.Storage;
import com.magima.core.connect.listener.ServerDataListener;

public class RepositoryStorage<T> extends Storage<T> {
	private Repository repository;
	private Class<?> typeOfT;
	protected Lock mLock = new ReentrantLock(true);
	private Gson mGson;
	
	public RepositoryStorage(Repository repository, Class<?> typeOfT) {
		this.repository = repository;
		this.typeOfT = typeOfT;
		mGson = new GsonBuilder().create();
	}

	public Repository getRepository() {
		return repository;
	}

	public void setRepository(Repository repository) {
		this.repository = repository;
		if ( repository != null ) {
			Lock lock = repository.getLock(); //如果repository有锁，就用repository的锁，否则就用自己的锁
			if ( lock != null )
				mLock = lock;
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public void read(final Collection<T> collection,
			final ServerDataListener<List<T>> listener,
			HashMap<String, Object> options) {
		if (repository != null) {
			List<String> strings = repository.loadAllString();
			List<T> data = new ArrayList<T>();
			for (String str : strings) {
				T o = (T) mGson.fromJson(str, typeOfT);
				data.add(o);
			}
			if (listener != null)
				listener.onSuccess(data, "");
		} else {
			if (listener != null)
				listener.onError();
		}
	}

	@Override
	public void create(final Collection<T> collection, T model,
			final ServerDataListener<T> listener,
			HashMap<String, Object> options) {
		if (repository != null) {
			mLock.lock();
			try {
				repository.saveString(collection.getId(model),
						mGson.toJson(model));
			} finally {
				mLock.unlock();
			}
			if (listener != null)
				listener.onSuccess(model, "");
		} else {
			if (listener != null)
				listener.onError();
		}
	}

	@Override
	public void delete(final Collection<T> collection, final Model<T> model,
			final ServerDataListener<T> listener,
			HashMap<String, Object> options) {
		if (repository != null) {
			mLock.lock();
			try {
				repository.remove(collection.getId(model.getModel()));
			} finally {
				mLock.unlock();
			}
			if (listener != null)
				listener.onSuccess(model.getModel(), "");
		} else {
			if (listener != null)
				listener.onError();
		}
	}

	@Override
	public void update(final Model<T> model, final T data,
			final ServerDataListener<T> listener,
			HashMap<String, Object> options) {
		if (repository != null) {
			mLock.lock();
			String id = model.getCollection() != null ? model.getCollection().getId(model.getModel()):"";
			try {
				repository.saveString(id, mGson.toJson(data));
			} finally {
				mLock.unlock();
			}
			if (listener != null)
				listener.onSuccess(model.getModel(), "");
		} else {
			if (listener != null)
				listener.onError();
		}
	}
}
